package org.androidpn.server.entity;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.androidpn.server.util.XMLUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

/**
 * entity 角色
 * 
 * @author 蔡琪
 * 
 */
@Entity
@Table(name = "tk_role")
public class Role extends BaseEntity {

	private static final long serialVersionUID = -3952643973194651016L;

	public enum RoleStatus {
		/** 可用 */
		enable,
		/** 不可用 */
		disable,
		/** 锁定 */
		locked
	}

	/** 昵称 */
	@NotEmpty
	@Length(max = 8, min = 2)
	@Column(name = "nickname", unique = true)
	private String nickname;

	/** 头像路径 */
	@Column(name = "avatar_src")
	private String avatarSrc;

	/** 胜利场数 */
	@Column(name = "games_won")
	private Long gamesWon;

	/** 失败场数 */
	@Column(name = "games_lost")
	private Long gamesLost;

	/** 总游戏场数 */
	@Column(name = "games_count")
	private Long gamesCount;

	/** 是否在线 */
	@Column(name = "is_online")
	private Boolean isOnline;

	/** 是否准备(游戏房间中的状态) */
	@Column(name = "isReady")
	private Boolean isReady;

	/** 角色状态 */
	@Column(name = "status")
	private RoleStatus status;

	/** 所属用户 */
	@ManyToOne(fetch = FetchType.EAGER)
	private User user;

	/** 当前所在房间 */
	@ManyToOne(fetch = FetchType.EAGER)
	private Room room;

	/** 好友 */
	@OneToMany(mappedBy = "role", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
	private Set<Friend> friends = new HashSet<Friend>();

	/** 好友分组 */
	@OneToMany(mappedBy = "role", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
	private Set<FriendGroup> friendGroups = new HashSet<FriendGroup>();

	/** 游戏操作信息 */
	@OneToMany(mappedBy = "role", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
	private Set<GameOperationInfo> gameOperationInfos = new HashSet<GameOperationInfo>();

	/** 拥有的房间 */
	@OneToMany(mappedBy = "host", cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
	private Set<Room> rooms = new HashSet<Room>();

	/** 广播消息 */
	@ManyToMany(cascade = CascadeType.PERSIST)
	@JoinTable(name = "role_broadcast", joinColumns = @JoinColumn(table = "tk_broadcast", name = "broadcast_id"), inverseJoinColumns = @JoinColumn(table = "tk_role", name = "role_id"))
	// 定义中间表,joinCollumns：table指向非维护字段所在的表，name是在中间表中的字段名；
	// inverseJoinColumns：table指向维护端所在的表，name是在中间表中的字段名
	private Set<Broadcast> broadcasts = new HashSet<Broadcast>();

	/** 房间消息 */
	@OneToMany(cascade = CascadeType.REMOVE)
	private Set<RoomMessage> roomMessages = new HashSet<RoomMessage>();

	/** 接收到的消息 */
	@OneToMany(mappedBy = "receiver", cascade = CascadeType.REMOVE)
	private Set<FriendMessage> receiveFriendMessages = new TreeSet<FriendMessage>(
			new Comparator<FriendMessage>() {
				public int compare(FriendMessage lhs, FriendMessage rhs) {
					return (int) (rhs.getCreateDate().getTime() - lhs
							.getCreateDate().getTime());
				}
			});
	/** 发送的消息 */
	@OneToMany(mappedBy = "sender", cascade = CascadeType.REMOVE)
	private Set<FriendMessage> sendFriendMessages = new TreeSet<FriendMessage>(
			new Comparator<FriendMessage>() {
				public int compare(FriendMessage lhs, FriendMessage rhs) {
					return (int) (rhs.getCreateDate().getTime() - lhs
							.getCreateDate().getTime());
				}
			});

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getAvatarSrc() {
		return avatarSrc;
	}

	public void setAvatarSrc(String avatarSrc) {
		this.avatarSrc = avatarSrc;
	}

	public Long getGamesWon() {
		return gamesWon;
	}

	public void setGamesWon(Long gamesWon) {
		this.gamesWon = gamesWon;
	}

	public Long getGamesLost() {
		return gamesLost;
	}

	public void setGamesLost(Long gamesLost) {
		this.gamesLost = gamesLost;
	}

	public Long getGamesCount() {
		return gamesCount;
	}

	public void setGamesCount(Long gamesCount) {
		this.gamesCount = gamesCount;
	}

	public Boolean getIsOnline() {
		return isOnline;
	}

	public void setIsOnline(Boolean isOnline) {
		this.isOnline = isOnline;
	}

	public Boolean getIsReady() {
		return isReady;
	}

	public void setIsReady(Boolean isReady) {
		this.isReady = isReady;
	}

	public RoleStatus getStatus() {
		return status;
	}

	public void setStatus(RoleStatus status) {
		this.status = status;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Room getRoom() {
		return room;
	}

	public void setRoom(Room room) {
		this.room = room;
	}

	public Set<Friend> getFriends() {
		return friends;
	}

	public void setFriends(Set<Friend> friends) {
		this.friends = friends;
	}

	public Set<FriendGroup> getFriendGroups() {
		return friendGroups;
	}

	public void setFriendGroups(Set<FriendGroup> friendGroups) {
		this.friendGroups = friendGroups;
	}

	public Set<GameOperationInfo> getGameOperationInfos() {
		return gameOperationInfos;
	}

	public void setGameOperationInfos(Set<GameOperationInfo> gameOperationInfos) {
		this.gameOperationInfos = gameOperationInfos;
	}

	public Set<Room> getRooms() {
		return rooms;
	}

	public void setRooms(Set<Room> rooms) {
		this.rooms = rooms;
	}

	public Set<Broadcast> getBroadcasts() {
		return broadcasts;
	}

	public void setBroadcasts(Set<Broadcast> broadcasts) {
		this.broadcasts = broadcasts;
	}

	public Set<RoomMessage> getRoomMessages() {
		return roomMessages;
	}

	public void setRoomMessages(Set<RoomMessage> roomMessages) {
		this.roomMessages = roomMessages;
	}

	public Set<FriendMessage> getReceiveFriendMessages() {
		return receiveFriendMessages;
	}

	public void setReceiveFriendMessages(
			Set<FriendMessage> receiveFriendMessages) {
		this.receiveFriendMessages = receiveFriendMessages;
	}

	public Set<FriendMessage> getSendFriendMessages() {
		return sendFriendMessages;
	}

	public void setSendFriendMessages(Set<FriendMessage> sendFriendMessages) {
		this.sendFriendMessages = sendFriendMessages;
	}

	/**
	 * 从xml字符串中解析出Role
	 * 
	 * @param xml
	 *            xml字符串
	 * @return Role对象
	 */
	@Transient
	public static Role fromXML(String xml) {
		Role role = BaseEntity.fromXML(xml, Role.class);
		Document doc;
		try {
			doc = DocumentHelper.parseText(xml);
			Element element = doc.getRootElement();
			String nickname = element.elementText("nickname");
			String avatarSrc = element.elementText("avatarSrc");
			String gamesWon = element.elementText("gamesWon");
			String gamesLost = element.elementText("gamesLost");
			String gamesCount = element.elementText("gamesCount");
			String isOnline = element.elementText("isOnline");
			String isReady = element.elementText("isReady");
			String status = element.elementText("status");

			role.setNickname(nickname);
			role.setAvatarSrc(avatarSrc);
			role.setGamesWon(XMLUtils.getLongFromStr(gamesWon));
			role.setGamesLost(XMLUtils.getLongFromStr(gamesLost));
			role.setGamesCount(XMLUtils.getLongFromStr(gamesCount));
			role.setIsOnline(XMLUtils.getBooleanFromStr(isOnline));
			role.setIsReady(XMLUtils.getBooleanFromStr(isReady));
			role.setStatus(XMLUtils.getRoleStatusFromStr(status));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return role;
	}

	/**
	 * 将当前对象转化为xml字符串
	 * 
	 * @return
	 */
	@Transient
	public String toXML() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("<role>");
		buffer.append(super.toXML());
		buffer.append(XMLUtils.createSingleNode("nickname", this.nickname));
		buffer.append(XMLUtils.createSingleNode("avatarSrc", this.avatarSrc));
		buffer.append(XMLUtils.createSingleNode("gamesWon", this.gamesWon));
		buffer.append(XMLUtils.createSingleNode("gamesLost", this.gamesLost));
		buffer.append(XMLUtils.createSingleNode("gamesCount", this.gamesCount));
		buffer.append(XMLUtils.createSingleNode("isOnline", this.isOnline));
		buffer.append(XMLUtils.createSingleNode("isReady", this.isReady));
		buffer.append(XMLUtils.createSingleNode("status", this.status));
		buffer.append("</role>");
		return buffer.toString();
	}
}
